<?php

namespace App\Http\Controllers\Client;

use App\Http\Controllers\Controller;
use App\Models\AdminUserModel;
use App\Models\yb\CouponModel;
use App\Models\yb\GoodsModel;
use App\Models\yb\GoodsOrderModel;
use App\Models\yb\NetworkGoodsModel;
use App\Models\yb\SettingModel;
use App\Models\yb\UserCouponModel;
use App\Models\yb\UserInvitationRecord;
use App\Models\yb\UserModel;
use App\Models\yb\UserAddressModel;
use App\Models\yb\UserWalletRecordModel;
use App\Models\yb\UserWaterTicketModel;
use App\Models\yb\UserWaterTicketRecordModel;
use App\Models\yb\WaterTicketModel;
use App\Models\yb\WaterTicketOrderModel;
use App\Models\yb\GoodsOrderDetailModel;
use Illuminate\Http\Request;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Yansongda\Pay\Pay;


class PayOrderController extends Controller
{

    /**
     * Get a JWT via given credentials.
     *  下单购买水票
     * @return \Illuminate\Http\JsonResponse
     */

    public function WaterTicketPayOrder(Request $request)
    {

        $openid = $request->post('openid');

        $user_data = UserModel::where(['openid'=>$openid])->first();

        if(empty($user_data)){
            return response()->json(['code'=>'401','msg' => '请登录']);
        }

        $water_ticket_id = $request->post('water_ticket_id');

        $water_ticket_data = WaterTicketModel::where(['id'=>$water_ticket_id,'status'=>1])->first();

        if(empty($water_ticket_data)){
            return response()->json(['code'=>'201','msg' => '该水票已下架']);
        }

        $orderSn = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

        WaterTicketOrderModel::insert([
            'order_sn'=>$orderSn,
            'user_id'=>$user_data['id'],
            'openid'=>$openid,
            'water_ticket_id'=>$water_ticket_id,
            'water_ticket_name'=>$water_ticket_data['water_ticket_name'],
            'amount'=> $water_ticket_data['amount_price'],
            'created_at'=>date('Y-m-d H:i:s',time())
        ]);

        try {
            $config = WaterTicketOrderModel::payByWeChat($orderSn,$openid,$water_ticket_data['amount_price']);
            return ['code' => 200, 'data' => $config];
        } catch (\Exception $e) {
            return ['code' => 404, 'massage' => $e->getMessage()];
        }
    }

    /**
     * Get a JWT via given credentials.
     *  下单购买水票回调
     * @return \Illuminate\Http\JsonResponse
     */
    public function WaterTicketNotifyUrl(){

        $payment = Factory::payment(WaterTicketOrderModel::getConfig());

        $response = $payment->handlePaidNotify(function ($message, $fail) {

            $order_data = WaterTicketOrderModel::where(['order_sn'=>$message['out_trade_no']])->first();

            if (!$order_data || $order_data['status']>0) {
                return true;
            }

            if ($message['return_code'] === 'SUCCESS') {
                //开启事务
                DB::beginTransaction();

                WaterTicketOrderModel::where(['order_sn'=>$message['out_trade_no']])->update([
                    'status'=>1,
                    'pay_time'=>date('Y-m-d H:i:s',time())
                ]);

                $user_water_ticket_data = UserWaterTicketModel::where(['user_id'=>$order_data['user_id'],'water_ticket_id'=>$order_data['water_ticket_id']])->first();

                $water_ticket_data = WaterTicketModel::where(['id'=>$order_data['water_ticket_id']])->first();

                $number = $water_ticket_data['promotion_by']+$water_ticket_data['promotion_give'];

                SettingModel::InverseIntegral($order_data['user_id'],$order_data['amount']);

                //修改水票数
                if(empty($user_water_ticket_data)){
                    UserWaterTicketModel::insert([
                        'user_id'=>$order_data['user_id'],
                        'openid'=>$order_data['openid'],
                        'goods_id'=>$water_ticket_data['goods_id'],
                        'water_ticket_id'=>$order_data['water_ticket_id'],
                        'water_ticket_name'=>$water_ticket_data['water_ticket_name'],
                        'number'=>$number,
                        'created_at'=>date('Y-m-d H:i:s',time())
                    ]);
                }else{
                    UserWaterTicketModel::where(['user_id'=>$order_data['user_id'],'water_ticket_id'=>$order_data['water_ticket_id']])->increment('number',$number);
                }

                //添加水票记录
                UserWaterTicketRecordModel::insert([
                    'user_id'=>$order_data['user_id'],
                    'openid'=>$order_data['openid'],
                    'water_ticket_id'=>$order_data['water_ticket_id'],
                    'water_ticket_name'=>$water_ticket_data['water_ticket_name'],
                    'number'=>$number,
                    'type'=>2,
                    'status'=>1,
                    'created_at'=>date('Y-m-d H:i:s',time()),
                ]);
                Db::commit();

                return true;

            } else {
                return $fail('通信失败，请稍后再通知我');
            }
        });
    }
    /**
     * Get a JWT via given credentials.
     *  商品下单
     * @return \Illuminate\Http\JsonResponse
     */
    public function GoodsPlace(Request $request){

        $openid = $request->post('openid');

        $user_data = UserModel::where(['openid'=>$openid])->first();

        if(empty($user_data)){
            return response()->json(['code'=>'401','msg' => '请登录']);
        }

        $address_id = $request->post('address_id');

        if(empty($address_id)){
            return response()->json(['code'=>'203','msg' => '地址不能为空']);
        }

        $user_address_data = UserAddressModel::where(['id'=>$address_id])->first();

        $delivery_date = $request->post('delivery_date');

        if(empty($delivery_date)){
            return response()->json(['code'=>'203','msg' => '请选择配送日期']);
        }

        $delivery_time = $request->post('delivery_time');

        if(empty($delivery_time)){
            return response()->json(['code'=>'203','msg' => '请选择配送时间']);
        }

        $network_id = $request->post('network_id');
        $network_data = AdminUserModel::where(['id'=>$network_id])->first();

        // $scope = $this->getdistance($user_address_data['latitude'],$user_address_data['longitude'],$network_data['latitude'],$network_data['longitude']);

        // if($network_data['distribution_scope']<$scope){
        //     return response()->json(['code'=>'203','msg' => '位置已超过配送范围,请重新选择网点或修改配送地址']);
        // }

        if(empty($network_data)){
            return response()->json(['code'=>'203','msg' => '请选择网点']);
        }

        $goods_list = $request->post('goods_list');

        if(empty($goods_list)){
            return response()->json(['code'=>'203','msg' => '请选择产品或数量']);
        }

        $goods_list = json_decode($goods_list,true);
        //实际需要支付金额
        $amount = 0;
        //优惠金额
        $discount_price = 0;
        //总价
        $total_price = 0;
        //水票优惠总金额
        $total_water_ticket_deduction = 0;
        //运费
        $total_freight = 0;


        $orderSn = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

        for($i=0;$i<count($goods_list);$i++){

            $goods_data = GoodsModel::where(['id'=>$goods_list[$i]['goods_id']])->first();

            $network_data = NetworkGoodsModel::where(['goods_id'=>$goods_list[$i]['goods_id'],'network_id'=>$network_id])->first();

            if(empty($goods_data) || empty($network_data) || $network_data['status']!=1){
                return response()->json(['code'=>'203','msg' => $goods_data['title'].'已下架']);
            }

            if($network_data['goods_stock']<$goods_list[$i]['number']){
                return response()->json(['code'=>'203','msg' => $goods_data['title'].'库存不足']);
            }

            $amount = $amount+$goods_data['goods_price']*$goods_list[$i]['number'];

            $total_price = $total_price+$goods_data['goods_price']*$goods_list[$i]['number'];

            $coupon_data = array();

            if(!empty($goods_list[$i]['coupon_id'])){

                $coupon_data = CouponModel::where(['id'=>$goods_list[$i]['coupon_id']])->first();

                if($goods_data['goods_price']*$goods_list[$i]['number'] < $coupon_data['promotion_full']){
                    return response()->json(['code'=>'203','msg' => '未满足优惠券使用要求']);
                }

                $user_coupon_data = UserCouponModel::where(['user_id'=>$user_data['id'],'coupon_id'=>$goods_list[$i]['coupon_id'],'is_used'=>0,'status'=>1])->first();
                if(empty($user_coupon_data)){
                    return response()->json(['code'=>'203','msg' => '您未领取此优惠券或优惠券已过期']);
                }

                UserCouponModel::where(['id'=>$user_coupon_data['id']])->update([
                    'is_used'=>1,
                    'usage_time'=>date('Y-m-d H:i:s',time()),
                ]);

                CouponModel::where(['id'=>$goods_list[$i]['coupon_id']])->increment('used_number');

                $discount_price = $discount_price+$coupon_data['promotion_reduce'];

                $amount = $amount-$coupon_data['promotion_reduce'];
            }

            if($goods_list[$i]['type'] == 2){
                $water_ticket_deduction_number = $goods_list[$i]['number'];
            }else{
                $water_ticket_deduction_number = 0;
            }

            $promotion_reduce =empty($coupon_data['promotion_reduce'])?0:$coupon_data['promotion_reduce'];

            $total_freight = $total_freight+$goods_data['freight'];

            $order_data_detail[] = [
                'order_sn' => $orderSn,
                'user_id' => $user_data['id'],
                'network_id' => $network_id,
                'goods_id' => $goods_list[$i]['goods_id'],
                'coupon_id' => $goods_list[$i]['coupon_id'],
                'goods_price' => $goods_data['goods_price'],
                'number' => $goods_list[$i]['number'],
                'type' => $goods_list[$i]['type'],
                'total_price' => $goods_data['goods_price']*$goods_list[$i]['number'],
                'amount' => $goods_data['goods_price']*$goods_list[$i]['number']-$promotion_reduce,
                'freight' => $goods_data['freight'],
                // 'barrel_deposit' => $goods_data['barrel_deposit'],
                'water_ticket_deduction_number' => $water_ticket_deduction_number,
                'water_ticket_deduction' => $goods_data['goods_price']*$water_ticket_deduction_number,
                'distribution_fee' => $goods_data['distribution_fee'],
                'coupon_deduction' => $promotion_reduce,
                'created_at' => date('Y-m-d H:i:s',time())
            ];

            $total_water_ticket_deduction = $total_water_ticket_deduction+$goods_data['goods_price']*$water_ticket_deduction_number;

        }

        $insert_data = [
            'order_sn' => $orderSn,
            'user_id' => $user_data['id'],
            'openid' => $openid,
            'address_id' => $address_id,
            'total_price' => $total_price,
            'discount_price'=>$discount_price,
            'delivery_date' => $delivery_date,
            'delivery_time' => $delivery_time,
            'network_id'=>$network_id,
            'total_water_ticket_deduction' => $total_water_ticket_deduction,
            'network_openid'=>$network_data['openid'],
            'created_at' => date('Y-m-d H:i:s',time())
        ];

        // //桶押金
        // if($is_barrel_deposit == 1 && $goods_data['is_barrel_deposit']==1 && $goods_data['barrel_deposit'] > 0){
        //     $insert_data['is_barrel_deposit'] = $is_barrel_deposit;
        //     $insert_data['barrel_deposit'] = $goods_data['barrel_deposit']*$number;
        //     $amount = $amount+$insert_data['barrel_deposit'];
        //     $total_price = $total_price+$insert_data['barrel_deposit'];
        // }
        $amount =  $amount-$total_water_ticket_deduction;
        //上楼费
        $setting_data = SettingModel::select(['is_todoor_fee','todoor_fee_floor','todoor_amount','is_delivery_fee','delivery_fee'])->first();
        if($setting_data['is_todoor_fee'] == 1 && $user_address_data['stair_type'] == 2 && $user_address_data['floor']>$setting_data['todoor_fee_floor']){
            $insert_data['is_todoor_fee'] = 1;
            $insert_data['todoor_amount'] = $setting_data['todoor_amount'];
            $amount = $amount+$insert_data['todoor_amount'];
            $total_price = $total_price+$insert_data['todoor_amount'];
        }
        //配送费
        if($setting_data['is_delivery_fee'] == 1 && $total_price>=$setting_data['delivery_fee']){
            $total_freight = 0;
        }

        $insert_data['amount'] = $amount+$total_freight;
        $insert_data['total_freight'] = $total_freight;
        $insert_data['total_price'] = $total_price+$total_freight;

        GoodsOrderModel::insert($insert_data);

        if($total_freight == 0){
            foreach($order_data_detail as $key=>$val){
                $order_data_detail[$key]['freight'] = 0;
            }
        }

        GoodsOrderDetailModel::insert($order_data_detail);

        $data['order_sn'] = $orderSn;

        return response()->json(['code'=>'200','msg' => '请求成功','data'=>$data]);

    }

    /**
     * Get a JWT via given credentials.
     *  商品下单支付
     * @return \Illuminate\Http\JsonResponse
     */
    public function GoodsPay(Request $request){

        $openid = $request->post('openid');

        $user_data = UserModel::where(['openid'=>$openid])->first();
        if(empty($user_data)){
            return response()->json(['code'=>'401','msg' => '请登录']);
        }

        $order_sn = $request->post('order_sn');

        $order_data = GoodsOrderModel::where(['order_sn'=>$order_sn])->first();

        if(empty($order_data) || $order_data['status']>0){
            return response()->json(['code'=>'203','msg' => '请重新下单']);
        }

        DB::beginTransaction();

        try {
            $config = array();

            if($order_data['amount']>0){
                if(!empty($order_data['payment_time'])){
                    $minute=floor((time()-strtotime($order_data['payment_time']))%86400/60);
                    if($minute<15){
                        $config = json_decode($order_data['pay_sigin']);
                    }
                }else{
//                    $order_data['amount'] = 0.01;
                    $config = GoodsOrderModel::payByWeChat($order_data['order_sn'],$openid,$order_data['amount']);

                    GoodsOrderModel::where(['order_sn'=>$order_data['order_sn']])->update([
                        'payment_time' => date('Y-m-d H:i:s',time()),
                        'pay_sigin' => json_encode($config)
                    ]);
                }
            }else{
                $this->OrderSuccessRecord($order_sn);
                GoodsOrderModel::where(['order_sn'=>$order_sn])->update([
                    'pay_time'=>date('Y-m-d H:i:s',time()),
                    'status'=>1,
                ]);
            }

            Db::commit();

            return response()->json(['code'=>'200','msg' => '请求成功','data'=>$config]);

        } catch (\Exception $e) {
            return ['code' => 404, 'massage' => $e->getMessage()];
        }

    }

    /**
     * Get a JWT via given credentials.
     *  商品下单支付
     * @return \Illuminate\Http\JsonResponse
     */
    public function GoodsAlipayPay(Request $request){

        $order_sn = $request->post('order_sn');

        $order_data = GoodsOrderModel::where(['order_sn'=>$order_sn])->first();

        if(empty($order_data) || $order_data['status']>0){
            return response()->json(['code'=>'203','msg' => '请重新下单']);
        }

        DB::beginTransaction();

        try {
            $datas = array();

            if($order_data['amount']>0){


                $order_data['amount'] = 1;

                $sign_data['app_id']=env('DOUYIN_CLIENT_APP_ID');
                $sign_data['out_order_no']=$order_sn;
                $sign_data['total_amount']=$order_data['amount']+0;
                $sign_data['subject']="易宝到家";
                $sign_data['body']="易宝到家";
                $sign_data['valid_time']=9000;
                $sign_data['notify_url']="https://www.njshenb.cn/api/order/goods/douyin/notify_url";

                $sign = $this->sign($sign_data);

                $client =new \GuzzleHttp\Client();

                $res = $client->request('POST','https://developer.toutiao.com/api/apps/ecpay/v1/create_order',[
                    'json'=>[
                        'app_id'=>env('DOUYIN_CLIENT_APP_ID'),
                        'out_order_no'=>$order_sn,
                        'total_amount'=>$order_data['amount']+0,
                        'subject'=>"易宝到家",
                        'body'=>"易宝到家",
                        'valid_time'=>9000,
                        'notify_url'=>"https://www.njshenb.cn/api/order/goods/douyin/notify_url",
                        'sign'=>$sign,
                    ],

                    'headers' => ['Content-type'=> 'application/json']
                ]);

                $datas = json_decode((string)$res->getBody(), true);

                GoodsOrderModel::where(['order_sn'=>$order_data['order_sn']])->update([
                    'payment_time' => date('Y-m-d H:i:s',time()),
                    'pay_sigin' => json_encode($datas)
                ]);

                if($datas['err_no'] == 0){
                    return response()->json(['code'=>'200','msg' => '请求成功','data'=>$datas['data']]);
                }else{
                    return response()->json(['code'=>'203','msg' => '请求失败','data'=>$datas['err_tips']]);
                }

            }else{

                $this->OrderSuccessRecord($order_sn);
                GoodsOrderModel::where(['order_sn'=>$order_sn])->update([
                    'pay_time'=>date('Y-m-d H:i:s',time()),
                    'status'=>1,
                ]);
            }

            Db::commit();

            return response()->json(['code'=>'200','msg' => '请求成功','data'=>$datas]);

        } catch (\Exception $e) {
            return ['code' => 404, 'massage' => $e->getMessage()];
        }

    }

    function sign($map) {
        $rList = array();
        foreach($map as $k =>$v) {
            if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
                continue;
            $value = trim(strval($v));
            $len = strlen($value);
            if ($len > 1 && substr($value, 0,1)=="\"" && substr($value,$len, $len-1)=="\"")
                $value = substr($value,1, $len-1);
            $value = trim($value);
            if ($value == "" || $value == "null")
                continue;
            array_push($rList, $value);
        }
        array_push($rList, "tiK3wJbw1MGhpAxm5tmrZsTDkQbiezrI9R2T35CG");
        sort($rList, 2);
        return md5(implode('&', $rList));
    }

    /**
     * Get a JWT via given credentials.
     *  商品下单回调
     * @return \Illuminate\Http\JsonResponse
     */
    public function GoodsNotifyUrl(Request $request){

        $payment = Factory::payment(GoodsOrderModel::getConfig());

        $response = $payment->handlePaidNotify(function ($message, $fail) {
            $order_data = GoodsOrderModel::where(['order_sn'=>$message['out_trade_no']])->first();
            if(empty($order_data) || $order_data['status']>0){
                return true;
            }

            if ($message['return_code'] === 'SUCCESS') {
                //开启事务
                DB::beginTransaction();

                GoodsOrderModel::where(['order_sn'=>$message['out_trade_no']])->update([
                    'pay_time'=>date('Y-m-d H:i:s',time()),
                    'payment_type' => 3,
                    'status'=>1,
                ]);

                SettingModel::InverseIntegral($order_data['user_id'],$order_data['amount']);

                $this->OrderSuccessRecord($message['out_trade_no']);

                Db::commit();

                return true;

            } else {
                return $fail('通信失败，请稍后再通知我');
            }
        });

    }

    /**
     * Get a JWT via given credentials.
     *  抖音商品下单回调
     * @return \Illuminate\Http\JsonResponse
     */
    public function GoodsDouyinPay(Request $request){

        $data = $request->input();

        $msg = json_decode($data['msg'],true);

        $order_data = GoodsOrderModel::where(['order_sn'=>$msg['cp_orderno']])->first();
        if(empty($order_data) || $order_data['status']>0){
            return response()->json(['err_no'=>'0','err_tips' => 'success']);

        }

        if($data['type'] == 'payment'){
            //开启事务
            DB::beginTransaction();

            GoodsOrderModel::where(['order_sn'=>$msg['cp_orderno']])->update([
                'pay_time'=>date('Y-m-d H:i:s',time()),
                'payment_type' => $msg['way'],
                'status'=>1,
            ]);

            SettingModel::InverseIntegral($order_data['user_id'],$order_data['amount']);

            $this->OrderSuccessRecord($msg['cp_orderno']);

            Db::commit();

            return response()->json(['err_no'=>'0','err_tips' => 'success']);

        }
    }

    //根据经纬度计算距离
    function getdistance($lng1,$lat1,$lng2,$lat2)
    {
        //将角度转为狐度
        $radLat1=deg2rad($lat1);
        $radLat2=deg2rad($lat2);
        $radLng1=deg2rad($lng1);
        $radLng2=deg2rad($lng2);
        $a=$radLat1-$radLat2;//两纬度之差,纬度<90
        $b=$radLng1-$radLng2;//两经度之差纬度<180
        $s=2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137;
        return $s;
    }

    function OrderSuccessRecord($order_sn){

        $goods_order_detail = GoodsOrderDetailModel::where(['order_sn'=>$order_sn])->get();

        $order_data = GoodsOrderModel::where(['order_sn'=>$order_sn])->first();

        $user_data = UserModel::where(['id'=>$order_data['user_id']])->first();

        foreach($goods_order_detail as $key=>$val){
            $goods_data = GoodsModel::where(['id'=>$val['goods_id']])->first();
            if($val['type'] == 2){

                $user_water_ticket_data = UserWaterTicketModel::where(['user_id'=>$user_data['id'],'goods_id'=>$goods_data['goods_warehouse_id']])->first();

                if(empty($user_water_ticket_data) || $user_water_ticket_data['number']<$val['number']){
                    return response()->json(['code'=>'203','msg' => '水票不足请重新下单']);
                }

                UserWaterTicketModel::where(['user_id'=>$val['user_id'],'water_ticket_id'=>$user_water_ticket_data['water_ticket_id']])->decrement('number',$val['number']);
                //添加水票记录
                UserWaterTicketRecordModel::insert([
                    'user_id'=>$val['user_id'],
                    'openid'=>$user_data['openid'],
                    'water_ticket_id'=>$user_water_ticket_data['water_ticket_id'],
                    'water_ticket_name'=>$user_water_ticket_data['water_ticket_name'],
                    'number'=>$val['number'],
                    'type'=>1,
                    'status'=>0,
                    'created_at'=>date('Y-m-d H:i:s',time()),
                ]);
            }
            GoodsModel::where(['id'=>$val['goods_id']])->increment('goods_sales');
            NetworkGoodsModel::where(['goods_id'=>$val['goods_id'],'network_id'=>$val['network_id']])->decrement('goods_stock');
            NetworkGoodsModel::where(['goods_id'=>$val['goods_id'],'network_id'=>$val['network_id']])->increment('goods_sales');
        }

        if(!empty($user_data['inviter_user_id'])){
            $user_invitation_record_data = UserInvitationRecord::where(['invitation_id'=>$user_data['id'],'user_id'=>$user_data['inviter_user_id']])->first();
            if(!empty($user_invitation_record_data)&&$user_invitation_record_data['is_orders'] == 0){
                $inviter_user_data = UserModel::where(['id'=>$user_data['inviter_user_id']])->first();
                if(!empty($inviter_user_data)){
                    $setting_data = SettingModel::select(['invitation_reward'])->first();
                    UserInvitationRecord::where(['id'=>$user_invitation_record_data['id']])->update(['is_orders'=>1]);
                    if($setting_data['invitation_reward']>0){
                        UserModel::where(['id'=>$user_data['inviter_user_id']])->update([
                            'guests_number' => $inviter_user_data['guests_number']+1,
                            'earn_points' => $inviter_user_data['earn_points']+$setting_data['invitation_reward']
                        ]);
                        UserWalletRecordModel::insert([
                            'user_id'=>$inviter_user_data['id'],
                            'openid'=>$inviter_user_data['openid'],
                            'avatar'=>$inviter_user_data['avatar'],
                            'phone'=>$inviter_user_data['phone'],
                            'nickname'=>$inviter_user_data['nickname'],
                            'amount'=>$setting_data['invitation_reward'],
                            'status'=>1,
                            'remark'=>'邀请奖励',
                            'created_at'=>date('Y-m-d H:i:s',time())
                        ]);
                    }
                }
            }
        }

        $admin_data = AdminUserModel::where(['id'=>$order_data['network_id']])->select('wechat_openid')->first();
        if(!empty($admin_data['wechat_openid'])){
            GoodsOrderModel::orderPush($admin_data['wechat_openid'],$order_sn);
        }
    }

}
